/*

The contents of this web application are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this web application except in compliance with the License. 
You may obtain a copy of the License at http://www.mozilla.org/MPL/.

Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
See the License for the specific language governing rights and limitations under the License.

The Original Code is owned by and the Initial Developer of the Original Code is Composite A/S (Danish business reg.no. 21744409). All Rights Reserved

Section 11 of the License is EXPRESSLY amended to include a provision stating that any dispute, including but not limited to disputes related to the enforcement of the License, to which Composite A/S as owner of the Original Code, as Initial Developer or in any other role, becomes a part to shall be governed by Danish law and be initiated before the Copenhagen City Court ("K�benhavns Byret")
                        
*/

using System;
using System.Collections.Generic;

using Composite.C1Console.Events;
using Composite.Core.Logging;


namespace Composite.Functions
{
    internal static class FunctionEventSystemFacade
    {
        internal delegate void FunctionsAddedEventDelegate(FunctionsAddedEventArgs args);
        internal delegate void FunctionsRemovedEventDelegate(FunctionsRemovedEventArgs args);
        internal delegate void WidgetFunctionsAddedEventDelegate(WidgetFunctionsAddedEventArgs args);
        internal delegate void WidgetFunctionsRemovedEventDelegate(WidgetFunctionsRemovedEventArgs args);

        private static event FunctionsAddedEventDelegate _functionsAddedEvent;
        private static event FunctionsRemovedEventDelegate _functionsRemovedEvent;
        private static event WidgetFunctionsAddedEventDelegate _widgetFunctionsAddedEvent;
        private static event WidgetFunctionsRemovedEventDelegate _widgetFunctionsRemovedEvent;

        private static object _lock = new object();


        static FunctionEventSystemFacade()
        {
            GlobalEventSystemFacade.SubscribeToFlushEvent(OnFlushEvent);
        }



        public static void SubscribeToFunctionsAddedEvent(FunctionsAddedEventDelegate functionsAddedEventDelegate)
        {
            lock (_lock)
            {
                _functionsAddedEvent += functionsAddedEventDelegate;
            }
        }



        public static void SubscribeToFunctionsRemovedEvent(FunctionsRemovedEventDelegate functionsRemovedEventDelegate)
        {
            lock (_lock)
            {
                _functionsRemovedEvent += functionsRemovedEventDelegate;
            }
        }



        public static void SubscribeToWidgetFunctionsAddedEvent(WidgetFunctionsAddedEventDelegate widgetFunctionsAddedEventDelegate)
        {
            lock (_lock)
            {
                _widgetFunctionsAddedEvent += widgetFunctionsAddedEventDelegate;
            }
        }



        public static void SubscribeToWidgetFunctionsRemovedEvent(WidgetFunctionsRemovedEventDelegate widgetFunctionsRemovedEventDelegate)
        {
            lock (_lock)
            {
                _widgetFunctionsRemovedEvent += widgetFunctionsRemovedEventDelegate;
            }
        }



        public static void FireFunctionAddedEvent(FunctionsAddedEventArgs functionsAddedEventArgs)
        {
            lock (_lock)
            {
                if (_functionsAddedEvent != null)
                {
                    FunctionsAddedEventDelegate functionsAddedEvent = _functionsAddedEvent;

                    functionsAddedEvent(functionsAddedEventArgs);
                }
            }
        }



        public static void FireFunctionRemovedEvent(FunctionsRemovedEventArgs functionsRemovedEventArgs)
        {
            lock (_lock)
            {
                if (_functionsRemovedEvent != null)
                {
                    FunctionsRemovedEventDelegate functionsRemovedEvent = _functionsRemovedEvent;

                    functionsRemovedEvent(functionsRemovedEventArgs);
                }
            }
        }



        public static void FireWidgetFunctionAddedEvent(WidgetFunctionsAddedEventArgs widgetFunctionsAddedEventArgs)
        {
            lock (_lock)
            {
                if (_widgetFunctionsAddedEvent != null)
                {
                    WidgetFunctionsAddedEventDelegate widgetFunctionsAddedEvent = _widgetFunctionsAddedEvent;

                    widgetFunctionsAddedEvent(widgetFunctionsAddedEventArgs);
                }
            }
        }



        public static void FireWidgetFunctionRemovedEvent(WidgetFunctionsRemovedEventArgs widgetFunctionsRemovedEventArgs)
        {
            lock (_lock)
            {
                if (_widgetFunctionsRemovedEvent != null)
                {
                    WidgetFunctionsRemovedEventDelegate widgetFunctionsRemovedEvent = _widgetFunctionsRemovedEvent;

                    widgetFunctionsRemovedEvent(widgetFunctionsRemovedEventArgs);
                }
            }
        }



        private static void Flush()
        {
            lock (_lock)
            {
                _functionsAddedEvent = null;
                _functionsRemovedEvent = null;
                _widgetFunctionsAddedEvent = null;
                _widgetFunctionsRemovedEvent = null;
            }
        }



        private static void OnFlushEvent(FlushEventArgs args)
        {
            Flush();
        }
    }





    internal sealed class FunctionsAddedEventArgs : EventArgs
    {
        internal FunctionsAddedEventArgs(List<string> functionsAdded)
        {
            this.FunctionsAdded = functionsAdded;
        }


        public List<string> FunctionsAdded
        {
            get;
            private set;
        }
    }



    internal sealed class FunctionsRemovedEventArgs : EventArgs
    {
        internal FunctionsRemovedEventArgs(List<string> functionsRemoved)
        {
            this.FunctionsRemoved = functionsRemoved;
        }


        public List<string> FunctionsRemoved
        {
            get;
            private set;
        }
    }



    internal sealed class WidgetFunctionsAddedEventArgs : EventArgs
    {
        internal WidgetFunctionsAddedEventArgs(List<string> widgetFunctionsAdded)
        {
            this.WidgetFunctionsAdded = widgetFunctionsAdded;
        }


        public List<string> WidgetFunctionsAdded
        {
            get;
            private set;
        }
    }



    internal sealed class WidgetFunctionsRemovedEventArgs : EventArgs
    {
        internal WidgetFunctionsRemovedEventArgs(List<string> widgetFunctionsRemoved)
        {
            this.WidgetFunctionsRemoved = widgetFunctionsRemoved;
        }


        public List<string> WidgetFunctionsRemoved
        {
            get;
            private set;
        }
    }
}
